<template>
    <div>
        <el-switch
            v-model="draggable"
            active-text="开启拖拽"
            inactive-text="关闭拖拽">
        </el-switch>
        <el-button type="primary" v-if="draggable" @click="batchSave">批量保存拖拽</el-button>
        <el-button type="danger" @click="batchDelele">批量删除</el-button>
        <el-tree
            :data="menus"
            :props="defaultProps"
            :show-checkbox="true"
            node-key="catId"
            :expand-on-click-node="false"
            :default-expanded-keys="expandedKey"
            :draggable="draggable"
            :allow-drop="allowDrop" 
            @node-drop="handleDrop"
            ref="menuTree">

            <span class="custom-tree-node" slot-scope="{ node, data }">
                <span>{{ node.label }}</span>
                <span>
                    <el-button
                        v-if="data.catLevel <= 2"
                        type="text"
                        size="mini"
                        @click="() => append(data)">
                        Append
                    </el-button>
                    <el-button
                        type="text"
                        size="mini"
                        @click="() => update(data)">
                        Update
                    </el-button>
                    <el-button
                        v-if="data.children == null||data.children.length == 0"
                        type="text"
                        size="mini"
                        @click="() => remove(node, data)">
                        Delete
                    </el-button>
                </span>
            </span>
        </el-tree>

        <!--新增/修改商品分类对话框-->
        <el-dialog :title="dialogTitle" :visible.sync="dialogFormVisible" :close-on-click-modal="false">
            <el-form :model="category">
                <el-form-item label="商品分类名称">
                    <el-input v-model="category.name" autocomplete="off"></el-input>
                </el-form-item>
                <el-form-item label="图标">
                    <el-input v-model="category.icon" autocomplete="off"></el-input>
                </el-form-item>
                <el-form-item label="计量单位">
                    <el-input v-model="category.productUnit" autocomplete="off"></el-input>
                </el-form-item>
            </el-form>
            <div slot="footer" class="dialog-footer">
                <el-button @click="dialogFormVisible = false">取 消</el-button>
                <el-button type="primary" @click="submitType">确 定</el-button>
            </div>
        </el-dialog>

    </div>
</template>


<script>
// 这里可以导入其他文件（比如：组件，工具 js，第三方插件 js，json文件，图片文件等等）
// 例如：import 《组件名称》 from '《组件路径》';

export default {
    // import 引入的组件需要注入到对象中才能使用
    components: {},
    props: {},
    data() {
        return {
            draggable: false,
            updateNodes:[],
            maxLevel: 0,
            pCids: [],
            dialogFormVisible: false,
            dialogType : "",
            dialogTitle : "",
            category: {
                catId:0,
                name: '',
                parentCid:0,
                catLevel:0,
                showStatus:1,
                sort:0,
                icon:'',
                productUnit:''
            },
            expandedKey: [],
            menus: [],
            defaultProps: {
                children: "children",
                label: "name",
            },
        };
    },
    methods: {
        //从服务器获取所有商品分类数据
        getMenus() {
            this.$http({
                url: this.$http.adornUrl("/product/category/list/tree"),
                method: "get"
            }).then(({ data }) => {
                this.menus = data.data;
            });
        },
        batchDelele(){
            let catIds = [];
            let catNames = [];
            let checkedNodes = this.$refs.menuTree.getCheckedNodes();
            console.log("被选中的节点",checkedNodes);
            for(let i=0;i<checkedNodes.length;i++){
                catIds.push(checkedNodes[i].catId);
                catNames.push(checkedNodes[i].name);
                this.$confirm(`此操作将删除分类【${catNames}】, 是否继续?`, '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    this.$http({
                        url: this.$http.adornUrl("/product/category/delete"),
                        method: "post",
                        data: this.$http.adornData(catIds, false),
                    }).then(({data})=>{
                        this.$message({
                            type: 'success',
                            message: '批量删除商品分类成功!'
                        });
                        //更新最新菜单数据
                        this.getMenus();
                        //设置默认展开的菜单
                        // this.expandedKey = [node.parent.data.catId];
                    }).catch(() => {
                        this.$message({
                            type: 'error',
                            message: '删除操作异常'
                        });          
                    });
                    
                }).catch(() => {
                    this.$message({
                        type: 'info',
                        message: '已取消删除'
                    });          
                });
            }
        },
        batchSave(){
            this.$http({
                url: this.$http.adornUrl('/product/category/update/sort'),
                method: 'post',
                data: this.$http.adornData(this.updateNodes, false)
            }).then(({ data }) => {
                this.$message({
                    type: 'success',
                    message: '商品分类拖拽批量保存成功!'
                }); 
                //更新最新菜单数据
                this.getMenus();
                //设置默认展开的菜单
                this.expandedKey = this.pCids;
                this.updateNodes = [];//拖拽成功后给updateNodes清零
                
            });
        },
        handleDrop(draggingNode, dropNode, dropType, ev) {
            console.log('tree drop: ', draggingNode,dropNode, dropType,ev);
            //只将draggingNode的catLevel和parentCid更新
            let data = [];//用于保存被拖拽节点以及所有兄弟节点需要修改的值
            let siblings = null;
            let pCid = 0;
            if(dropType=="inner"){
                pCid = dropNode.data.catId;
                siblings = dropNode.childNodes;
            }else if(dropType=="after"||dropType=="before"){
                pCid = dropNode.data.parentCid;
                siblings = dropNode.parent.childNodes;
            }
            this.pCids.push(pCid);
            //由于elements组件自动将拖拽的节点加入到了dropNode或dropNode.parent的childNodes属性中了
            //所以下面步骤无需考虑被拖拽节点draggingNode不在siblings中需要手动加入进行排序sort属性赋值的情况
            for(let i=0;i<siblings.length;i++){
                if(siblings[i].data.catId==draggingNode.data.catId){
                //如果遍历到当前正在拖拽的节点,需要多传入两个个参数parentCid,catLevel
                    let cLevel = siblings[i].level;
                    if(siblings[i].level != draggingNode.level){
                        cLevel = siblings[i].level;
                        //修改当前节点以及所有子节点的层级，及catLevel属性
                        this.updateChildNodeLevel(siblings[i]);
                    }
                    
                    this.updateNodes.push({catId:siblings[i].data.catId,catLevel:cLevel,parentCid:pCid,sort:i});

                }else{
                    this.updateNodes.push({catId:siblings[i].data.catId,sort:i});
                }
            }
            console.log("updateNodes",this.updateNodes);
            this.$message({
                type: 'success',
                message: '商品拖拽成功，完成所有拖拽后记得保存哦!'
            }); 
            
            //将下面的请求放到button绑定的batchSave方法中，点击button按钮才进行一次统一的提交，降低服务器压力
            // this.$http({
            //     url: this.$http.adornUrl('/product/category/update/sort'),
            //     method: 'post',
            //     data: this.$http.adornData(this.updateNodes, false)
            // }).then(({ data }) => {
            //     this.$message({
            //         type: 'success',
            //         message: '商品分类拖拽成功!'
            //     }); 
            //     //更新最新菜单数据
            //     this.getMenus();
            //     //设置默认展开的菜单
            //     console.log(dropNode.data);
            //     this.expandedKey = [pCid];
            //     this.updateNodes = [];//拖拽成功后给updateNodes清零
            // });
        },
        //修改子节点的层级
        updateChildNodeLevel(node){
            if(node.childNodes.length>0){
                for(let i=0;i<node.childNodes.length;i++){
                    let cNode = node.childNodes[i];
                    this.updateNodes.push({catId:cNode.data.catId,catLevel:cNode.level});
                    this.updateChildNodeLevel(cNode);
                }
            }
            

        },
        allowDrop(draggingNode, dropNode, type) {
            //1. 如果type为before|after：被拖动节点draggingNode的层数以及dropNode所在的父节点层数 之和不能大于3 
            //2. 如果type为inner：被拖动节点draggingNode的层数以及dropNode所在的层数 之和不能大于3 
            this.maxLevel = draggingNode.level;//不能初始化为0，否则当draggingNode没子节点时执行countNodeLevel后还是0
            this.countNodeLevel(draggingNode);
            //1）统计被拖动节点draggingNode的层数——(被拖拽节点的最大深度-被拖拽节点的层数+1)
            //被拖拽节点的最大深度
            let draggingDeep = Math.abs(this.maxLevel-draggingNode.level)+1;
            //如果是inner，则判断(被拖动节点draggingNode的层数以及dropNode所在的父节点总层数不能大于3)
            if(type=="inner"){
                return (draggingDeep + dropNode.level) <=3 ;
            }else{
                return (draggingDeep + dropNode.parent.level) <=3 ;
            }
            
        },
        //统计当前节点与所有子节点组成的最大深度
        countNodeLevel(node){
            //遍历所有子节点，找出最大深度
            if(node.childNodes!=null&&node.childNodes.length!=0){
                for(let i=0;i<node.childNodes.length;i++){
                    if(node.childNodes[i].level > this.maxLevel){
                        this.maxLevel = node.childNodes[i].level;
                    }
                    this.countNodeLevel(node.childNodes[i]);
                }
                return;
            }
        },
        //用于判断dialog确定按钮绑定的事件
        submitType(){
            if(this.dialogType=="append"){
                this.comfirmAppend();
            }else if(this.dialogType="update"){
                this.comfirmUpdate();
            }
        },
        // 对话框确认点击事件，点击则向服务器发送post请求
        comfirmUpdate(){
            this.dialogFormVisible = false;//关闭更新对话框
            //解构出需要发送的数据
            var {catId,name,icon,productUnit} = this.category;
            var data = {catId,name,icon,productUnit};
            console.log("待发送的数据",data);
            this.$http({
                url: this.$http.adornUrl('/product/category/update'),
                method: 'post',
                data: this.$http.adornData(data, false)
            }).then(({ data }) => {
               this.$message({
                    type: 'success',
                    message: '更新成功!'
                }); 
                //更新最新菜单数据
                this.getMenus();
                //设置默认展开的菜单
                console.log(this.category.parentCid+":");
                this.expandedKey = [this.category.parentCid];
            });

        },
        //更新子商品分类功能
        update(data) {
            //修改dialog相关信息
            this.dialogTitle = "更新商品分类名称"
            this.dialogType = "update";
            this.dialogFormVisible = true;//显示更新对话框
            //发送请求获取最新分类数据
            //传入参数parentCid，catLevel
            this.$http({
                url: this.$http.adornUrl(`/product/category/info/${data.catId}`),
                method: 'get'
            }).then(({data}) => {
                console.log("update:",data);
                this.category.catId = data.data.catId;
                this.category.name = data.data.name;
                this.category.icon = data.data.icon;
                this.category.productUnit = data.data.productUnit;
                this.category.parentCid = data.data.parentCid;
            })
            
            
        },
        // 对话框确认点击事件，点击则向服务器发送post请求
        comfirmAppend(){
            this.dialogFormVisible=false;//显示对话框
            console.log(this.category);
            this.$http({
                url: this.$http.adornUrl('/product/category/save'),
                method: 'post',
                data: this.$http.adornData(this.category, false)
            }).then(({ data }) => {
               this.$message({
                    type: 'success',
                    message: '添加成功!'
                }); 
                //更新最新菜单数据
                this.getMenus();
                //设置默认展开的菜单
                this.expandedKey = [this.category.parentCid];
            });

        },
        //增加子商品分类功能
        append(data) {
            //修改dialog相关信息
            this.dialogTitle = "增加子商品分类"
            console.log("append", data);
            this.dialogFormVisible = true;//显示对话框
            this.dialogType = "append";
            //传入参数parentCid，catLevel
            this.category.parentCid = data.catId;
            this.category.catLevel = data.catLevel*1+1;

            //清楚输入框中的默认信息
            this.category.catId = null;
            this.category.icon = "";
            this.category.productUnit = "";
            this.category.sort = 0;
            this.category.name = "";
            
        },
        //删除分类功能实现
        remove(node, data) {
            var ids = [data.catId];
            this.$confirm(`此操作将删除分类【${data.name}】, 是否继续?`, '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            }).then(() => {
                this.$http({
                    url: this.$http.adornUrl("/product/category/delete"),
                    method: "post",
                    data: this.$http.adornData(ids, false),
                }).then(({data})=>{
                    this.$message({
                        type: 'success',
                        message: '删除成功!'
                    });
                    //更新最新菜单数据
                    this.getMenus();
                    //设置默认展开的菜单
                    this.expandedKey = [node.parent.data.catId];
                }).catch(() => {
                    this.$message({
                        type: 'error',
                        message: '删除操作异常'
                    });          
                });
                
            }).catch(() => {
                this.$message({
                    type: 'info',
                    message: '已取消删除'
                });          
            });
            // const newChild = { id: id++, label: 'testtest', children: [] };
            // if (!data.children) {
            // this.$set(data, 'children', []);
            // }
            // data.children.push(newChild);
        },
        
    },

    // 计算属性 类似于 data 概念
    computed: {},

    // 监控 data 中的数据变化
    watch: {},

    // 生命周期 - 创建完成（可以访问当前 this 实例）
    created() {
        this.getMenus();
    },

    // 生命周期 - 挂载完成（可以访问 DOM 元素）
    mounted() {},

    beforeCreate() {}, // 生命周期 - 创建之前

    beforeMount() {}, // 生命周期 - 挂载之前

    beforeUpdate() {}, // 生命周期 - 更新之前

    updated() {}, // 生命周期 - 更新之后

    beforeDestroy() {}, // 生命周期 - 销毁之前

    destroyed() {}, // 生命周期 - 销毁完成

    activated() {}, // 如果页面有 keep-alive 缓存功能，这个函数会触发
};
</script>
 
<!--@import url(); 引入公共 css 类-->
<style scoped>
</style>